package com.wuliang.generate.common.core.configs;

import com.wuliang.generate.common.core.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 权限配置文件
 *
 * @author WuLiang
 */
@Slf4j
@Aspect
@Component
public class PermissionConfig {

    @Autowired
    private RedisUtils redisUtils;

    @Pointcut("@annotation(com.wuliang.generate.common.core.annotation.WxUserPermission)")
    public void permissionVerify() {

    }

    @Before("permissionVerify()")
    public void beforeMethod(JoinPoint joinPoint) {
        // 方法名
        String mappingMethodName = joinPoint.getSignature().getName();
        // Controller
        String controllerName = joinPoint.getSignature().getDeclaringType().getSimpleName();
        log.info("I will authentication the method which the method name is {}.{}", controllerName, mappingMethodName);
        Object[] argsValues = joinPoint.getArgs();
        String[] argsNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
        String token = null;
        for (int i = 0; i < argsValues.length; i++) {
            if (argsNames[i].equals("token")) {
                token = String.valueOf(argsValues[i]);
            }
        }
        if (token == null || token.isEmpty()) {
            throw new RuntimeException("您尚未登录");
        }
        /*
         * TODO 2020年11月19日 后面是对用户的鉴权操作。
         *  在想是要查MySQL，还是查redis。又或者是从 SecurityContextHolder 中获取。
         *  1. 如果是从MySQL查，那么在高并发场景中对于数据库的压力无疑是一场随时爆发的灾难；
         *  2. 如果是从Redis查，那么具体的存储格式，以及存储位置，应该做成什么样的。
         *  3. 如果是从 SecurityContextHolder 中获取，那么应该怎样才能做到这个上下文对象是在所有服务中是唯一的，或者说是同一个上下文持久化对象
         *  第一点，不太建议，还得做容灾...
         *  第二点的话，实现起来较为简单。就是登录的时候存储好用户的身份信息。
         *  第三点实现的话，我是想着可以用一个中间服务来管理这个对象。唔...   当然也可以直接用认证服务。 但是具体实现的话可能会比较复杂。
         */

    }

}
